﻿using System;
using System.Collections.Generic;

namespace BodaNetCommunications.Utilities.DataLibs
{
    //
    // 摘要:
    //     位转换库
    public class BitLib
    {
        //
        // 摘要:
        //     返回指定字节的指定位
        //
        // 参数:
        //   b:
        //     字节
        //
        //   offset:
        //     指定位（0-7）
        //
        // 返回结果:
        //     布尔结果
        public static bool GetBitFromByte(byte b, int offset)
        {
            if (offset >= 0 && offset <= 7)
            {
                return (b & (int)Math.Pow(2.0, offset)) != 0;
            }

            return false;
        }

        //
        // 摘要:
        //     返回字节数组中的某个字节某个位
        //
        // 参数:
        //   b:
        //     字节数组
        //
        //   index:
        //     字节索引
        //
        //   offset:
        //     指定位（0-7）
        //
        // 返回结果:
        //     布尔结果
        public static bool GetBitFromByteArray(byte[] b, int index, int offset)
        {
            byte[] byteArray = ByteArrayLib.GetByteArray(b, index, 1);
            return GetBitFromByte(byteArray[0], offset);
        }

        //
        // 摘要:
        //     返回两个字节的指定位
        //
        // 参数:
        //   b:
        //     两个字节
        //
        //   offset:
        //     指定位（0-15）
        //
        //   reverse:
        //     字节顺序
        //
        // 返回结果:
        //     布尔结果
        public static bool GetBitFrom2Byte(byte[] b, int offset, bool reverse = false)
        {
            byte b2 = reverse ? b[0] : b[1];
            byte b3 = reverse ? b[1] : b[0];
            if (offset >= 0 && offset <= 7)
            {
                return GetBitFromByte(b3, offset);
            }

            if (offset >= 8 && offset <= 15)
            {
                return GetBitFromByte(b2, offset - 8);
            }

            throw new Exception("索引必须为0-15之间");
        }

        //
        // 摘要:
        //     返回字节数组中某2个字节的指定位
        //
        // 参数:
        //   b:
        //     字节数组
        //
        //   index:
        //     字节索引
        //
        //   offset:
        //     指定位（0-15）
        //
        //   reverse:
        //     字节顺序
        //
        // 返回结果:
        //     布尔结果
        public static bool GetBitFrom2ByteArray(byte[] b, int index, int offset, bool reverse = false)
        {
            byte[] byteArray = ByteArrayLib.GetByteArray(b, index, 2);
            return GetBitFrom2Byte(byteArray, offset, reverse);
        }

        //
        // 摘要:
        //     根据一个Short返回指定位
        //
        // 参数:
        //   val:
        //     short数值
        //
        //   offset:
        //     指定位（0-15）
        //
        //   reverse:
        //     字节顺序
        //
        // 返回结果:
        //     布尔结果
        public static bool GetBitFromShort(short val, int offset, bool reverse = false)
        {
            return GetBitFrom2Byte(BitConverter.GetBytes(val), offset, reverse);
        }

        //
        // 摘要:
        //     根据一个UShort返回指定位
        //
        // 参数:
        //   val:
        //     ushort数值
        //
        //   offset:
        //     指定位（0-15）
        //
        //   reverse:
        //     字节顺序
        //
        // 返回结果:
        //     布尔结果
        public static bool GetBitFromUShort(ushort val, int offset, bool reverse = false)
        {
            return GetBitFrom2Byte(BitConverter.GetBytes(val), offset, reverse);
        }

        //
        // 摘要:
        //     将一个字节转换成布尔数组
        //
        // 参数:
        //   b:
        //     字节
        //
        //   reverse:
        //     位顺序
        //
        // 返回结果:
        //     布尔数组
        public static bool[] GetBitArrayFromByte(byte b, bool reverse = false)
        {
            bool[] array = new bool[8];
            if (reverse)
            {
                for (int num = 7; num >= 0; num--)
                {
                    array[num] = (b & 1) == 1;
                    b >>= 1;
                }
            }
            else
            {
                for (int i = 0; i <= 7; i++)
                {
                    array[i] = (b & 1) == 1;
                    b >>= 1;
                }
            }

            return array;
        }

        //
        // 摘要:
        //     将一个字节数组转换成布尔数组
        //
        // 参数:
        //   b:
        //     字节数组
        //
        //   reverse:
        //     位顺序
        //
        // 返回结果:
        //     布尔数组
        public static bool[] GetBitArrayFromByteArray(byte[] b, bool reverse = false)
        {
            List<bool> list = new List<bool>();
            foreach (byte b2 in b)
            {
                list.AddRange(GetBitArrayFromByte(b2, reverse));
            }

            return list.ToArray();
        }
    }
}